use crate::{util, xencode};

pub fn gen_challenge_req(username: &str) -> String {
    let callbackstr = "jQuery".to_string() + &util::get_timestamp();
    let usernamestr = urlencoding::encode(username).into_owned();
    let req = format!("callback={}&username={}", callbackstr, usernamestr);
    req
}

pub fn gen_check_req() -> String {
    let callbackstr = "jQuery".to_string() + &util::get_timestamp();
    let req = format!("callback={}", callbackstr);
    req
}

pub fn gen_login_req(ac_id: &str, username: &str, password: &str, client_ip: &str, challenge: &str) -> String {
    let callbackstr = "jQuery".to_string() + &util::get_timestamp();
    let actionstr = "login".to_owned();
    let nstr = "200".to_owned();
    let typestr = "1".to_owned();
    let ipstr = client_ip.to_owned();
    let usernamestr = urlencoding::encode(username).into_owned();
    let hmd5 = util::hex_hmac_md5(/*USER_PASSWORD*/ "", challenge);
    let passwordstr = urlencoding::encode(&("{MD5}".to_owned() + &hmd5)).into_owned();
    let infojson = format!(
        "{{\"username\":\"{}\",\"password\":\"{}\",\"ip\":\"{}\",\"acid\":\"{}\",\"enc_ver\":\"srun_bx1\"}}", 
        username, password, client_ip, ac_id
    );
    let info = "{SRBX1}".to_owned() + 
        &util::base64_mod_encode(
            &xencode::encode(&infojson, challenge)
        );
    let infostr = urlencoding::encode(&info);
    let checksumstr = util::hex_sha1(
        &(challenge.to_owned() + username + challenge + &hmd5 + challenge + ac_id + challenge + &ipstr + challenge + &nstr + challenge + &typestr + challenge + &info)
    );
    let req = format!(
        "callback={}&action={}&n={}&type={}&ac_id={}&ip={}&username={}&password={}&info={}&chksum={}", 
        callbackstr, actionstr, nstr, typestr, ac_id, ipstr, usernamestr, passwordstr, infostr, checksumstr
    );
    req
}

pub fn gen_logout_req(username: &str) -> String {
    let callbackstr = "jQuery".to_string() + &util::get_timestamp();
    let actionstr = "logout".to_owned();
    let usernamestr = urlencoding::encode(username).into_owned();
    let req = format!("callback={}&action={}&username={}", callbackstr, actionstr, usernamestr);
    req
}

pub fn send_req(url: &str, reqstr:&str) -> json::JsonValue {
    let target = url.to_owned() + "?" + reqstr;
    println!("Request: {}", target);
    let resp = reqwest::blocking::get(target).unwrap().text().unwrap();
    println!("Response: {}", resp);
    let jsonobj = json::parse(&resp[20..resp.len()-1]).unwrap();
    jsonobj
}

pub fn check_resp(jsonobj: &json::JsonValue) -> bool {
    if jsonobj.is_empty() {
        return false;
    }
    if !jsonobj.has_key("res") {
        return false;
    }
    let res = &jsonobj["res"];
    if res != "ok" {
        let error = &jsonobj["error"];
        let error_msg = &jsonobj["error_msg"];
        println!("An error occurred: {}, {}, {}", res, error, error_msg);
        return false;
    }
    return true;
}
